package city.spring.modules.oldman.controller;

import city.spring.modules.bed.service.BedManagementService;
import city.spring.modules.bed.vo.BedInfoVO;
import city.spring.modules.oldman.entity.ServiceReservationRecordEntity;
import city.spring.modules.oldman.service.ServiceReservationRecordService;
import city.spring.modules.oldman.vo.ServiceReservationRecordEntityVO;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.NonNull;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.SortDefault;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

/**
 * Controller：
 * 服务预定记录
 *
 * @author pxm
 * @date 2020-08-19 15:52:29
 */
@RestController
@RequestMapping("/service_reservation_record")
public class ServiceReservationRecordController extends ApiController {
    private final ServiceReservationRecordService serviceReservationRecordService;
    private final BedManagementService bedManagementService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<ServiceReservationRecordEntity, ?>> entityOrderFields;

    public ServiceReservationRecordController(ServiceReservationRecordService serviceReservationRecordService, BedManagementService bedManagementService) {
        this.serviceReservationRecordService = serviceReservationRecordService;
        this.bedManagementService = bedManagementService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(ServiceReservationRecordEntity::getId);
        entityOrderFields.add(ServiceReservationRecordEntity::getOrderNum);
        entityOrderFields.add(ServiceReservationRecordEntity::getOldmanId);
        entityOrderFields.add(ServiceReservationRecordEntity::getBedNumber);
        entityOrderFields.add(ServiceReservationRecordEntity::getProjectId);
        entityOrderFields.add(ServiceReservationRecordEntity::getServiceCount);
        entityOrderFields.add(ServiceReservationRecordEntity::getReceiveFee);
        entityOrderFields.add(ServiceReservationRecordEntity::getOrderTime);
        entityOrderFields.add(ServiceReservationRecordEntity::getServiceTime);
        entityOrderFields.add(ServiceReservationRecordEntity::getOrderStatus);
        entityOrderFields.add(ServiceReservationRecordEntity::getPayStatus);
        entityOrderFields.add(ServiceReservationRecordEntity::getGmtCreate);
        entityOrderFields.add(ServiceReservationRecordEntity::getGmtModified);
    }

    /**
     * 获取全部的 <strong>
     * 服务预定记录</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault Pageable pageable, ServiceReservationRecordEntity entity) {
        LambdaQueryChainWrapper<ServiceReservationRecordEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

    /**
     * 分页获取 <strong>
     * 服务预定记录</strong> 列表
     *
     * @param pageable 分页参数信息
     */
    @GetMapping
    public Object list(@PageableDefault @SortDefault.SortDefaults({@SortDefault(sort = "order_time", direction = Sort.Direction.DESC)}) Pageable pageable, ServiceReservationRecordEntityVO entity) {
        QueryWrapper<? extends ServiceReservationRecordEntity> queryWrapper = buildQuery(entity);
        return success(serviceReservationRecordService.listPage(MyBatisUtils.toPage(pageable), queryWrapper));
    }

    /**
     * 获取一个 <strong>
     * 服务预定记录</strong>
     *
     * @param id 主键ID
     */
    @GetMapping("{id}")
    public Object info(@PathVariable String id) {
        QueryWrapper<ServiceReservationRecordEntityVO> wrapper = new QueryWrapper<>();
        wrapper.eq("t1.id", id);
        List<ServiceReservationRecordEntityVO> records = serviceReservationRecordService.listPage(new Page<>(), wrapper).getRecords();
        if (records.isEmpty()) {
            return success(null);
        }
        return success(records.get(0));
    }

    /**
     * 根据老人ID获取床位号(楼-层-房-床)
     */
    @GetMapping("getOldmanBedInfo/{oldmanId}")
    public Object getOldmanBedInfo(@PathVariable String oldmanId) {
        BedInfoVO bedInfo = bedManagementService.getOldmanBed(oldmanId);
        String build = bedInfo.getBuilding().getName();
        String floor = bedInfo.getFloor().getName();
        String room = bedInfo.getRoom().getName();
        String bed = bedInfo.getBed().getName();
        String bedNumber = build + floor + room + bed;
        return success(bedNumber);
    }

    /**
     * 添加一个 <strong>
     * 服务预定记录</strong>
     *
     * @param entity 修改后的信息
     */
    @PostMapping
    public Object add(@RequestBody ServiceReservationRecordEntity entity, @NonNull Principal user) {
        serviceReservationRecordService.saveServiceReservationRecord(entity, user);
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    /**
     * 修改一个 <strong>
     * 服务预定记录</strong>
     *
     * @param id     主键ID
     * @param entity 修改后的信息
     */
    @PutMapping("{id}")
    public Object update(@PathVariable String id, @RequestBody ServiceReservationRecordEntity entity) {
        entity.setId(id);
        serviceReservationRecordService.updateServiceReservationRecord(entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 服务订单执行状态更改
     *
     * @param id
     * @return
     */
    @PutMapping("/orderStatusChange/{id}")
    public Object orderStatusChange(@PathVariable String id, @RequestBody ServiceReservationRecordEntity entity) {
        serviceReservationRecordService.orderStatusChange(id, entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 已支付但未执行的的订单，退款，且订单执行和支付状态改为“已取消”
     *
     * @param id
     * @return
     */
    @PutMapping("/orderCancel/{id}")
    public Object orderStatusChange(@PathVariable String id, @NonNull Principal user) {
        serviceReservationRecordService.orderCancel(id, user);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 退住结算： 获取未执行订单 的相关信息 ，用于结算前的预定服务的退款
     *
     * @param oldmanId
     * @return
     */
    @GetMapping("unExecuted/{oldmanId}")
    public Object unExecutedProject(@PathVariable String oldmanId) {
        Object[] objs = serviceReservationRecordService.getUnExecutedProject(oldmanId);
        return objs;
    }

    /**
     * 删除一个 <strong>
     * 服务预定记录</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        serviceReservationRecordService.deleteServiceReservationRecord(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong>
     * 服务预定记录</strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        serviceReservationRecordService.deleteServiceReservationRecord(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<ServiceReservationRecordEntity> buildLambdaQuery(ServiceReservationRecordEntity entity) {
        LambdaQueryChainWrapper<ServiceReservationRecordEntity> lambdaQuery = serviceReservationRecordService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), ServiceReservationRecordEntity::getId, entity.getId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getOrderNum()), ServiceReservationRecordEntity::getOrderNum, entity.getOrderNum());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getOldmanId()), ServiceReservationRecordEntity::getOldmanId, entity.getOldmanId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getProjectId()), ServiceReservationRecordEntity::getProjectId, entity.getProjectId());
        lambdaQuery.eq(entity.getServiceCount() != null, ServiceReservationRecordEntity::getServiceCount, entity.getServiceCount());
        lambdaQuery.eq(entity.getReceiveFee() != null, ServiceReservationRecordEntity::getReceiveFee, entity.getReceiveFee());
        lambdaQuery.eq(entity.getOrderTime() != null, ServiceReservationRecordEntity::getOrderTime, entity.getOrderTime());
        lambdaQuery.eq(entity.getServiceTime() != null, ServiceReservationRecordEntity::getServiceTime, entity.getServiceTime());
        lambdaQuery.eq(entity.getOrderStatus() != null, ServiceReservationRecordEntity::getOrderStatus, entity.getOrderStatus());
        lambdaQuery.eq(entity.getPayStatus() != null, ServiceReservationRecordEntity::getPayStatus, entity.getPayStatus());
        lambdaQuery.eq(entity.getGmtCreate() != null, ServiceReservationRecordEntity::getGmtCreate, entity.getGmtCreate());
        lambdaQuery.eq(entity.getGmtModified() != null, ServiceReservationRecordEntity::getGmtModified, entity.getGmtModified());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private QueryWrapper<? extends ServiceReservationRecordEntity> buildQuery(ServiceReservationRecordEntityVO entity) {
        QueryWrapper<? extends ServiceReservationRecordEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "t1.id", entity.getId());
        wrapper.like(StringUtils.isNotBlank(entity.getOrderNum()), "t1.order_num", entity.getOrderNum());
        wrapper.like(StringUtils.isNotBlank(entity.getOldmanId()), "t1.oldman_id", entity.getOldmanId());
        wrapper.like(StringUtils.isNotBlank(entity.getBedNumber()), "t1.bed_number", entity.getBedNumber());
        wrapper.like(StringUtils.isNotBlank(entity.getOldmanName()), "t3.oldman_name", entity.getOldmanName());
        wrapper.like(StringUtils.isNotBlank(entity.getProjectId()), "t1.project_id", entity.getProjectId());
        wrapper.like(StringUtils.isNotBlank(entity.getProjectName()), "t2.name", entity.getProjectName());
        wrapper.eq(entity.getServiceCount() != null, "t1.service_count", entity.getServiceCount());
        wrapper.eq(entity.getReceiveFee() != null, "t1.receive_fee", entity.getReceiveFee());
        wrapper.eq(entity.getOrderTime() != null, "t1.order_time", entity.getOrderTime());
        wrapper.eq(entity.getServiceTime() != null, "t1.service_time", entity.getServiceTime());
        wrapper.eq(entity.getOrderStatus() != null, "t1.order_status", entity.getOrderStatus());
        wrapper.eq(entity.getPayStatus() != null, "t1.pay_status", entity.getPayStatus());
        wrapper.eq(entity.getGmtCreate() != null, "t1.gmt_create", entity.getGmtCreate());
        wrapper.eq(entity.getGmtModified() != null, "t1.gmt_modified", entity.getGmtModified());
        return wrapper;
    }

}
